using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using EventBus;
using Statistics.Count;
using Statistics.Trace;
using UnityEngine;

namespace Statistics.Logger.TimeLogger
{
    /// <summary>
    /// 时间统计
    /// </summary>
    public class BroadcastTimeLogger : IBroadcast
    {
        private readonly IBroadcast _broadcaster;

        public BroadcastTimeLogger(IBroadcast broadcaster, IEventTracer eventTracer)
        {
            _broadcaster = broadcaster;
            _eventLogs.Push(eventTracer.AddEvent("Test"));
        }

        public void AddListener(string eventName, object callback)
        {
            var eventLog = BeginSample();

            _broadcaster.AddListener(eventName, callback);
            
            eventLog.Log($"添加事件监听 耗时:{eventLog.ElapsedTimeMs:F02}");
            EndSample(eventLog);
        }

        public int RemoveListener(string eventName, object callback)
        {
            var sw = ValueStopwatch.StartNew();
            var count = _broadcaster.RemoveListener(eventName, callback);
            Debug.Log($"移除事件监听 耗时:{sw.GetElapsedTime().Milliseconds:F02}");
            return count;
        }

        public bool BroadcastAction<T1, T2, T3, T4, T5, T6, T7, T8>(string eventName, int argCount, T1 arg1, T2 arg2,
            T3 arg3,
            T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
        {
            var eventLog = BeginSample();
            
            var result = _broadcaster.BroadcastAction(eventName, argCount, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);

            eventLog.Log($"广播事件 耗时:{eventLog.ElapsedTimeMs:F02}");
            EndSample(eventLog);

            return result;
        }

        public async UniTask<bool> BroadcastActionAsync<T1, T2, T3, T4, T5, T6, T7, T8>(string eventName, int argCount,
            T1 arg1, T2 arg2,
            T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
        {
            var sw = ValueStopwatch.StartNew();
            var result = await _broadcaster.BroadcastActionAsync(eventName, argCount, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
            Debug.Log($"广播事件 耗时:{sw.GetElapsedTime().Milliseconds:F02}");
            return result;
        }

        public TResult BroadcastFunc<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(string eventName, int argCount, T1 arg1,
            T2 arg2,
            T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
        {
            var sw = ValueStopwatch.StartNew();
            var result = _broadcaster.BroadcastFunc<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(eventName, argCount, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
            Debug.Log($"广播事件 耗时:{sw.GetElapsedTime().Milliseconds:F02}");
            return result;
        }

        public async UniTask<TResult> BroadcastFuncAsync<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(string eventName,
            int argCount, T1 arg1,
            T2 arg2,
            T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8)
        {
            var sw = ValueStopwatch.StartNew();
            var result = await _broadcaster.BroadcastFuncAsync<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(eventName, argCount, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
            Debug.Log($"广播事件 耗时:{sw.GetElapsedTime().Milliseconds:F02}");
            return result;
        }

        private readonly Stack<IEventLog> _eventLogs = new Stack<IEventLog>();
        
        private IEventLog BeginSample()
        {
            var eventLog = _eventLogs.Peek().AddChild();
            //_eventLogs.Push(eventLog);
            eventLog.BeginSample();
            return eventLog;
        }

        private void EndSample(IEventLog eventLog)
        {
            eventLog.EndSample();
            //_eventLogs.Pop();
        }
    }
}